<?php

namespace App\Jobs;

use App\Models\Admin\Supplier;
use App\Models\Admin\SupplierBalanceChangeRecord;
use App\Models\Mysql\XnMechantProfit;
use App\Models\Mysql\XnMerchant;
use App\Models\Mysql\XnMerchantBill;
use App\Models\Mysql\XnOrder;
use App\Models\Mysql\XnOrderBill;
use Chuoke\RmbCapital\RmbCapital;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Log;
use Throwable;

class OrderCallbackNotify implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     */
    public function __construct(public Supplier $supplier, public XnOrder $order, public bool $result, public string $errMessage = '充值失败')
    {

    }

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        try {
            $this->supplier->connection()->transaction(function() {
                $this->result ? $this->success() : $this->error();
            });
            $this->notify();

        } catch (Throwable $e) {
            Log::channel('job')->error('回调异常:' . $e->getMessage(), [
                'supplier'  => $this->supplier->toArray(),
                'order'     => $this->order->toArray(),
                'result'    => $this->result,
                'errMessage'=> $this->errMessage,
                'error'     => error2array($e),
            ]);
        }
    }


    public function notify()
    {
        try {
            if ($this->order->callback_url != "") {
                /** @var XnMerchant $merchants **/
                $merchants = XnMerchant::query()->where('merchant_number', $this->order['merchant_number'])->first();
                $post = [
                    'business_number'=>$merchants->merchant_number,
                    'order_num'=>$this->order->order_sn,
                    'status'=>$this->order->recharge_status,
                ];
                $post['sign'] = md5(json_encode($post) . $merchants->secret_key);
                $result = httpClient()->post($this->order->callback_url, $post)->body();
                if (strtolower($result) === 'ok') {
                    return true;
                }
                throw new Exception("返回的数据不是ok:[".$result."]");
            }
        } catch (Throwable $e) {
            Log::channel('job')->error('第三方回调异常:' . $e->getMessage(), [
                'supplier'  => $this->supplier->toArray(),
                'order'     => $this->order->toArray(),
                'result'    => $this->result,
                'errMessage'=> $this->errMessage,
                'error'     => error2array($e),
            ]);
        }
    }

    /**
     * @return void
     */
    protected function success(): void
    {
        /** @var Supplier $supplier **/
        $supplier = Supplier::query()->find($this->supplier->id);
        $this->order->update(['recharge_status' => 1, 'update_time' => date('Y-m-d H:i:s')]);
        XnOrderBill::query()->where('order_sn', $this->order['order_sn'])->update(['recharge_status' => 1]);
        XnMerchantBill::query()->where('merchant_order', $this->order['order_sn'])->update(['trading_status' => 1]);
        [$year, $month, $day] = explode('-', date('Y-m-d'));
        XnMechantProfit::query()->updateOrCreate(
            ['year'=>$year,'month'=>$month,'day'=>$day,'mechant_number'=>$this->order['merchant_number'],'order_type'=>$this->order['order_type']],
            ['create_time'=>date('Y-m-d H:i:s'),'income_number'=>Db::raw('income_number+1'),
                'income_money'=>Db::raw('income_money+' . $this->order->all_money),
                'profit'=>Db::raw('profit+'.($this->order['price']-$this->order['unitPrice']))]);
    }

    /**
     * @return void
     */
    protected function error(): void
    {
        /** @var XnMerchant $merchants **/
        $merchants = XnMerchant::query()->where('merchant_number', $this->order['merchant_number'])->first();
        /** @var XnMerchantBill $merchantBills **/
        $merchantBills = XnMerchantBill::query()->where('merchant_order', $this->order['order_sn'])->first();
        /** @var XnOrderBill $supplierBills **/
        $supplierBills = XnOrderBill::query()->where('order_sn', $this->order['order_sn'])->first();
        $merchantBillInfo = [
            'merchant_number' => $merchantBills['merchant_number'],
            'status' => 3,
            'before_transaction_balance' => $merchants['balance']- $merchants['deduction_balance'],
            'transaction_amount' => $merchantBills['transaction_amount'],
            'after_transaction_balance' => ($merchants['balance']- $merchants['deduction_balance'] + $merchantBills['transaction_amount']),
            'merchant_order' => $merchantBills['merchant_order'],
            'trading_status' => 2,
            'commission' => $merchantBills['commission'],
            'time' => date('Y-m-d H:i:s'),
            'brand_id' => $merchantBills['brand_id']
        ];
        $supplierBillInfo = [
            'goods_explain' => $supplierBills['goods_explain'],
            'bookkeeping_type' => 2,
            'order_sn' => $supplierBills['order_sn'],
            'account' => $supplierBills['account'],
            'price' => $supplierBills['price'],
            'goods_num' => $supplierBills['goods_num'],
            'business_type' => $supplierBills['business_type'],
            'budget_money' => $supplierBills['budget_money'],
            'recharge_status' => 4,
            'goods_belong' => $supplierBills['goods_belong'],
            'refund_time' => date('Y-m-d H:i:s'),
            'ctime' => $supplierBills['ctime'],
            'Merchant_name' => $supplierBills['merchant_name'],
            'goods_id' => $supplierBills['goods_id'],
            'brand_id' => $supplierBills['brand_id'],
            'order_type' => $supplierBills['order_type'],
            'merchant_number' => $merchants['merchant_number'],
            'mechant_balance' => ($merchants['balance']- $merchants['deduction_balance'] + $supplierBills['budget_money']),
            'mechant_before_balance' => $merchants['balance'] - $merchants['deduction_balance'],
            'mechant_after_balance' => ($merchants['balance'] - $merchants['deduction_balance'] + $merchantBills['transaction_amount']),
        ];
        $this->order->update(['recharge_status' => 2, 'msg' => $this->errMessage]);
        $supplierBills->update(['recharge_status' => 2]);
        $merchantBills->update(['trading_status' => 2]);
        $merchants->newQuery()->where('id', $merchants->id)->increment('balance', $this->order->all_money);
        XnOrderBill::query()->insert($supplierBillInfo);
        XnMerchantBill::query()->insert($merchantBillInfo);
    }
}

